using Aurora.TaskScheduler.Abstractions.Message;
using Aurora.TaskScheduler.Abstractions.Storage;
using SqlSugar;

namespace Aurora.TaskScheduler.Storage.MySql;

/// <summary>
/// mysql task 仓储实现类
/// </summary>
public class MysqlDataStorage : IDataStorage
{
    private readonly MySqlSugarContext _context;
    public SqlSugarScope Db { get; }

    public MysqlDataStorage(MySqlSugarContext context)
    {
        _context = context;
        Db = _context.Scope;
    }

    public async Task ExecuteCommand(string sql)
    {
        await Db.Ado.ExecuteCommandAsync(sql);
    }

    public async Task<AppTask> GetDetail(string id)
    {
        return await Db.Queryable<AppTask>().Where(x => x.Id.Equals(id)).FirstAsync();
    }

    public async Task<AppTask> GetTaskByName(string taskName, string groupName)
    {
        return await Db.Queryable<AppTask>().Where(x => x.GroupName.Equals(groupName) && x.TaskName.Equals(taskName))
            .FirstAsync();
    }

    public async Task<(List<AppTaskLog> list, int total)> GetLogList(string id, int page, int size)
    {
        RefAsync<int> count = 0;
        var list = await Db.Queryable<AppTaskLog>()
            .Where(x => x.TaskId.Equals(id))
            .OrderByDescending(x => x.BeginDate)
            .ToPageListAsync(page, size, count);
        return (list, count);
    }

    public async Task<(List<AppTaskLog> list, int total)> GetLogList(string groupName, string taskName, int page,
        int size)
    {
        RefAsync<int> count = 0;
        var list = await Db.Queryable<AppTaskLog>()
            .Where(x => x.TaskName.Equals(taskName) && x.GroupName.Equals(groupName))
            .OrderByDescending(x => x.BeginDate)
            .ToPageListAsync(page, size, count);
        return (list, count);
    }

    public async Task<List<AppTask>> GetAllJob(bool containerOne = false)
    {
        var list = await Db.Queryable<AppTask>()
            .Where(a => containerOne || !(a.TaskExecuteType ?? "").Equals("ONE")).ToListAsync();
        return list;
    }

    public async Task<string> Add(AppTask task)
    {
        task.Id = Guid.NewGuid().ToString();
        var count = await Db.Insertable<AppTask>(task).ExecuteCommandAsync();
        if (count <= 0)
            return string.Empty;
        return task.Id;
    }

    public async Task<string> Add(List<AppTask> tasks)
    {
        await Db.Insertable<AppTask>(tasks).ExecuteCommandAsync();
        return "1";
    }

    public async Task<string> AddLog(AppTaskLog log)
    {
        if (string.IsNullOrEmpty(log.Id))
            log.Id = Guid.NewGuid().ToString();
        //log.CreateTime = DateTime.Now;
        await Db.Insertable<AppTaskLog>(log).ExecuteCommandAsync();
        return log.Id;
    }

    public async Task<bool> Update(AppTask task)
    {
        task.LastModifiedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        await Db.Updateable<AppTask>(task).ExecuteCommandAsync();
        return true;
    }

    public async Task<bool> Update(List<AppTask> tasks)
    {
        await Db.Updateable<AppTask>(tasks).ExecuteCommandAsync();
        return true;
    }

    public async Task<bool> Remove(AppTask task)
    {
        await Db.Deleteable<AppTask>(task.Id).ExecuteCommandAsync();
        return true;
    }

    public async Task<List<AppTask>> GetListByTaskType(int taskType)
    {
        return await Db.Queryable<AppTask>().Where(x => x.TaskType == taskType).ToListAsync();
    }

    public async Task<AppTaskLog> GetLastLog(string taskName, string groupName)
    {
        return await Db.Queryable<AppTaskLog>().Where(x =>
            x.TaskName.Equals(taskName)
            && x.GroupName.Equals(groupName)
        ).OrderByDescending(x => x.CreateTime).FirstAsync();
    }

    public async Task<(List<AppTaskLog> list, int total)> GetExpireLog(DateTime expireTime, int page, int size)
    {
        RefAsync<int> total = 0;
        var data = await Db.Queryable<AppTaskLog>().Where(x => x.CreateTime <= expireTime
        ).OrderByDescending(x => x.CreateTime).ToPageListAsync(page, size, total);
        return (data, total);
    }

    public async Task<bool> RemoveLog(string id)
    {
        await Db.Deleteable<AppTaskLog>(id).ExecuteCommandAsync();
        return true;
    }

    public async Task<bool> RemoveLogRange(List<string> ids)
    {
        await Db.Deleteable<AppTaskLog>(ids).ExecuteCommandAsync();
        return true;
    }
}